home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr29 / keybuf20.zip / KEYBUF.ASM < prev    next >
Assembly Source File  |  1993-05-28  |  7KB  |  182 lines

  1. ; Copyright (c) 1992-1993 by Vincenzo "Enzo" Romano
  2. ; All rights reserved.
  3. ; Vincenzo Romano appears on courtesy of Shq`n Soft (Pisa, ITALY)
  4.  
  5. title KEYBUF - Expands the keyboard buffer to 128 keystrokes
  6.  
  7. comment #
  8.  
  9. The use of this program implies the following disclaim.
  10.  
  11. LEGAL: THIS PROGRAM IS ABSOLUTELY FREE OF ANY CHARGE FOR SINGLE USERS.
  12.        FOR COMMERCIAL USES, PLEASE CONTACT THE AUTHOR.
  13.        THE AUTHOR WILL NOT BE RESPONSIBLE OF ANY KIND OF DAMAGE DUED
  14.        TO THE USE OF THIS PROGRAM.
  15.        THE USER WILL USE THIS PROGRAM AT HIS OWN RISK.
  16.  
  17. Problem: I use to work under UNIX and am accustomed to type command lines
  18.      before the program is ready to read it. This is not a problem in
  19.      UNIX but it's a big trouble  under MS-DOG: MS-DOG has a 32 bytes
  20.      (16 keystrokes) long buffer,  so I get a "beeeeep" and loose any
  21.      extra characters I  type  when my MS-DOG machine run outside its
  22.      keyboard buffer.
  23.  
  24. Solution: Write your own MS-DOG patch program or ... use KeyBuf!
  25.  
  26. Details: Every MS-DOG machine has a  16 keystrokes circular buffer in its
  27.      BIOS Variables Segment (BVS)  at 0040:001E.  In the BVS there're
  28.      4 variables too to manage this  buffer: the head and the tail of
  29.      the circular buffer,  the starting  address and the address used
  30.      to check the wrap around  of  the  first  2  pointers. By simply
  31.      changing these  variables  we  can  use  another memory block as
  32.      keyboard buffer.  Unluckyly these address are written as offsets
  33.      of the BVS so we cannot use any memory block but only those ones
  34.      we can reach as offsets relatively to the BVS (0040h).  Let's do
  35.      some simple calculations.  If  our buffer is 256 bytes long, the
  36.      maximum  offset  we  can  use  is 65535-256=65279 or 66303 as an
  37.      absolute memory address.  What's  the segment:offset format with
  38.      the lowest offset value to  express such an addrress? It's easy:
  39.      it's (66303 div 16):(66303 mod 16) = 4143:15 = 102Fh:Fh.
  40.      Thus, our memory block segment  is  to be lower than 1030h to be
  41.      useful as a keyboard buffer.
  42.      If we run MS-DOG v5.00, we can load the MS-DOG itself in the HMA
  43.      and in some UMB leaving free our precious lower memory.
  44.      Anytime we run a program, MS-DOG prepends to it in memory a copy
  45.      of the variables environment.  This  copy is in higher memory if
  46.      we run the program high and is in lower memory if we run it low.
  47.      KeyBuf checks where it was loaded and uses its environment space
  48.      if it's running in low memory. Otherwise it allocates the buffer
  49.      in the lower available place.
  50.      Then it marks the buffer as owned by MS-DOG, sets the new values
  51.      in the BVS and then exits: KeyBuf is  not a resident program but
  52.      allocates a memory block and modifies the BVS accordingly.
  53.      For more technical details, please read the code below.
  54.  
  55.      I'd like to thank Ralph Brown for his "interrupts and memory map
  56.      compilation" a.k.a. INTERxx ( my version had xx=30 ): it was the
  57.      only useful documentation I used to write this little tool.
  58.  
  59.      For bugs and suggestions please contact me via e-mail:
  60.  
  61.              music@MILES.cnuce.cnr.it
  62.  
  63. #
  64.  
  65. BufLen    equ    256        ; New keyboard buffer lenght
  66. BVSeg    equ    0040h        ; BIOS variables segment (BVS)
  67. MaxSeg    equ    1030h        ; Highest suitable segment (read comment)
  68. DosOwn    equ    0008h        ; DOS memory block signature
  69. MCBOwn    equ    0001h        ; Memory Control Bock owner field
  70. StdBot    equ    001Eh        ; Usual buffer offset
  71.  
  72. BIOSVar    segment    byte at 0    ; BVS calculated relatively to segment 0000h
  73.     org    041Ah
  74. Head    dw    ?        ; Head pointer
  75. Tail    dw    ?        ; Tail pointer
  76.     org    0480h
  77. Bot    dw    ?        ; Starting offset of the buffer
  78. Top    dw    ?        ; Offset of the 1st word outside the buffer
  79. BIOSVar    ends
  80.  
  81. KeyBuf    segment    byte
  82.     assume    CS:KeyBuf, SS:KeyBuf, DS:KeyBuf, ES:nothing
  83.  
  84.     org    002Ch        ; Program environment segment in the PSP
  85. envseg    dw    ?        ; structure.
  86.  
  87.     org    0100h
  88. main:                ; Program (.COM) entry point
  89.     mov    DX,offset greet
  90.     mov    AH,09h
  91.     int    21h        ; Greeting message printout
  92.  
  93.     xor    AX,AX        ; First we see if KeyBuf was already loaded
  94.     mov    ES,AX        ; by inspecting the value of the BIOS variable
  95.     mov    AX,ES:Bot    ; used for the keyboard buffer.
  96.     cmp    AX,StdBot
  97.     je    first
  98.     mov    DX,offset alrdy
  99.     mov    AL,01h
  100.     jmp    exit
  101.  
  102. first:
  103.     mov    AH,48h        ; Now we allocate a 256 bytes (128 2-bytes
  104.     mov    BX,BufLen/16    ; keystrokes) memory block for our new buffer.
  105.     int    21h        ; If the program environment segment is not
  106.     jnc    allocok        ; useful (too little or too high in memory)
  107.     mov    AX,65535    ; we'll try to use this block.
  108.  
  109. allocok:
  110.     mov    DX,AX        ; Now we get our environment segment and
  111.     mov    AX,envseg    ; try to set its size to 256 bytes.
  112.     mov    ES,AX
  113.     mov    BX,BufLen/16
  114.     mov    AH,4Ah
  115.     int    21h
  116.  
  117.     jnc    envok        ; If the resize operation failed we set the
  118.     mov    AX,65535    ; the environment segment as FFFFh so it will
  119.     jmp    compare        ; seem to be too high for the program.
  120.  
  121. envok:
  122.     mov    AX,ES        ; We choose the lower segment between the
  123. compare:
  124.     cmp    DX,AX        ; environment and the allocated block and
  125.     ja    axok        ; put it in AX register.
  126.     mov    AX,DX
  127.  
  128. axok:
  129.     cmp    AX,MaxSeg    ; Finally we check if the segment in AX is
  130.     jb    segok        ; lower enough in memory to be useful.
  131.     mov    DX,offset toohi    ; Because of the tricks with FFFFh, maybe
  132.     mov    AL,02h        ; that niether the environment segment nor
  133.     jmp    exit        ; the allocated block is suitable, so ...
  134.  
  135. segok:
  136.     mov    DX,AX        ; We set the buffer as owned by DOS, so
  137.     dec    DX        ; when we'll exit the program the memory
  138.     mov    ES,DX        ; block will remain "resident".
  139.     mov    SI,MCBOwn
  140.     mov    DX,DosOwn
  141.     mov    ES:[SI],DX
  142.  
  143.     mov    CL,4        ; With simple calculations we translate
  144.     shl    AX,CL        ; our segment into an offset relatively
  145.     sub    AX,BVSeg*16    ; to the BVS. (seg*16) = (BVSeg*16)+off
  146.     mov    DX,AX        ; --> off = (seg*16)-(BVSeg*16)
  147.     add    DX,BufLen
  148.  
  149.     push    DS        ; We'll use DS to address the BVS to be
  150.     xor    CX,CX        ; as fast as we can while in the disabled
  151.     mov    DS,CX        ; interrupts section below.
  152.     assume    DS:BIOSVar
  153.  
  154.     cli            ; And now ... take the breath!
  155.     mov    Head,AX        ; While juggling with the BVS values
  156.     mov    Tail,AX        ; we have to avoid BIOS to modify those
  157.     mov    Bot,AX        ; values or we could get some incoherency.
  158.     mov    Top,DX
  159.     sti            ; Weew! You can breath normally, now!
  160.  
  161.     assume    DS:KeyBuf
  162.     pop    DS
  163.     mov    DX,offset allok    ; Successful message printout and exit
  164.     mov    AL,CL        ; with ERRORLEVEL set to 0.
  165.  
  166. exit:
  167.     mov    AH,09h
  168.     int    21h
  169.     mov    AH,4Ch        ; MS-DOG exit() service (AL = ERRORLEVEL)
  170.     int    21h
  171.  
  172. greet    db    'KeyBuf 2.00  (c) 1992-1993 by Shq`n Soft',13,10,'KEYBUF : ','$'
  173. alrdy    db    'already installed',13,10,'$'
  174. toohi    db    'all memory below 1030:0 is busy',13,10,'$'
  175. allok    db    'successfully installed',13,10,'$'
  176.  
  177. KeyBuf    ends
  178.  
  179. end    main
  180. ; That's all folks!
  181.  
  182.